{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Numpy实现SVD矩阵分解"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. 引入包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 实现矩阵分解"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.random.randint(1, 10, (8, 4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[6, 5, 1, 5],\n",
       "       [1, 7, 9, 7],\n",
       "       [7, 2, 4, 2],\n",
       "       [6, 4, 3, 5],\n",
       "       [2, 8, 8, 6],\n",
       "       [5, 2, 8, 6],\n",
       "       [7, 8, 2, 3],\n",
       "       [1, 3, 6, 9]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 实现矩阵分解\n",
    "U, S, V = np.linalg.svd(A, full_matrices=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((8, 4), (4,), (4, 4))"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U.shape, S.shape, V.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.28611227, -0.38768744, -0.07088588, -0.47757145],\n",
       "       [-0.44374671,  0.40390585, -0.25458601,  0.20383531],\n",
       "       [-0.24657791, -0.34884357,  0.43054458,  0.4062272 ],\n",
       "       [-0.30673084, -0.27495123,  0.14797683, -0.2218886 ],\n",
       "       [-0.43671345,  0.23339125, -0.39431663,  0.27599841],\n",
       "       [-0.37257929,  0.10313032,  0.59362412,  0.23542645],\n",
       "       [-0.33314069, -0.52514475, -0.41727103,  0.07285924],\n",
       "       [-0.35472167,  0.38520663,  0.20225001, -0.61580222]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([28.44730142, 10.24874824,  6.39012419,  4.56952014])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 因为是对角矩阵，这里进行了简写\n",
    "S"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[28.44730142,  0.        ,  0.        ,  0.        ],\n",
       "       [ 0.        , 10.24874824,  0.        ,  0.        ],\n",
       "       [ 0.        ,  0.        ,  6.39012419,  0.        ],\n",
       "       [ 0.        ,  0.        ,  0.        ,  4.56952014]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.diag(S)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.39194862, -0.50004828, -0.54329548, -0.54877866],\n",
       "       [-0.81202147, -0.18350883,  0.48594814,  0.26608277],\n",
       "       [ 0.41980592, -0.84227439,  0.27814277,  0.19228481],\n",
       "       [ 0.10373231,  0.08276523,  0.62555658, -0.76880979]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "V"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 从分量还原矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[6., 5., 1., 5.],\n",
       "       [1., 7., 9., 7.],\n",
       "       [7., 2., 4., 2.],\n",
       "       [6., 4., 3., 5.],\n",
       "       [2., 8., 8., 6.],\n",
       "       [5., 2., 8., 6.],\n",
       "       [7., 8., 2., 3.],\n",
       "       [1., 3., 6., 9.]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "U @ np.diag(S) @ V"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
